/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.servermanager.repository;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.metadata.rtcustomization.api.AbstractCustomizedContent;
import com.inspur.edp.metadata.rtcustomization.api.entity.GspMdChangeset;
import com.inspur.edp.metadata.rtcustomization.api.entity.GspMdChangesetHis;
import com.inspur.edp.metadata.rtcustomization.api.exception.LcmConfigResolveException;
import com.inspur.edp.metadata.rtcustomization.api.exception.ErrorCodes;
import com.inspur.edp.metadata.rtcustomization.common.CustomizedContentSerializerHelper;
import com.inspur.edp.metadata.rtcustomization.servermanager.CustomizationServiceContext;
import com.inspur.edp.metadata.rtcustomization.servermanager.dac.*;
import com.inspur.edp.metadata.rtcustomization.spi.CustomizationSerializer;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.UUID;

public class ChangeSetRepoService {
	private MetadataChangesetRepository changesetRepo;
	private  MetadataChangesetRepositoryHis changesetHisRepo;
	public ChangeSetRepoService( MetadataChangesetRepository changesetRepo, MetadataChangesetRepositoryHis changesetHisRepo) {
		this.changesetRepo=changesetRepo;
		this.changesetHisRepo=changesetHisRepo;
	}

	public GspMdChangeset getChangeset(String metadataId, String certId) {
		return changesetRepo.findByMetadataIdAndCertId(metadataId, certId);
	}

	public void saveChangeSet(GspMdChangeset changeset){
		GspMdChangesetHis changesetHis= BuildGspMdChangesetHis(changeset, changeset.getVersion());

		changesetRepo.save(changeset);

		changesetHisRepo.save(changesetHis);
	}
	public void deleteChangeSet(String metadataId){

		changesetRepo.deleteByMetadataId(metadataId);
		changesetHisRepo.deleteByMetadataId(metadataId);
	}

	public void saveChangeset(GspMetadata metadata, AbstractCustomizedContent customizedContent) {
		GspMdChangeset changeset =  changesetRepo.findByMetadataIdAndCertId(metadata.getHeader().getId(), metadata.getHeader().getCertId());
		GspMdChangesetHis changesetHis = null;
		if(changeset != null)
		{
			changesetHis = BuildGspMdChangesetHis(changeset, metadata.getVersion());
		}
		String id;
		if(changeset != null)
		{
			id = changeset.getId();
		}
		else
		{
			id = UUID.randomUUID().toString();
		}
		GspMdChangeset mdChangeset = BuildGspMdChangeset(metadata, customizedContent, id);
		if(mdChangeset != null)
		{
			changesetRepo.save(mdChangeset);
		}
		if(changesetHis != null)
		{
			changesetHisRepo.save(changesetHis);
		}
	}

	public void save(GspMdChangeset changeSet){
		GspMdChangeset oldChangeSet=getChangeset(changeSet.getMetadataId(),changeSet.getCertId());
		if(oldChangeSet!=null){
			saveHis(oldChangeSet,changeSet.getVersion());
		}
		changesetRepo.save(changeSet);
	}

	public void saveHis(GspMdChangeset changeset,String relatedVersion){
		GspMdChangesetHis changesetHis= BuildGspMdChangesetHis(changeset,relatedVersion);
		changesetHisRepo.save(changesetHis);
	}

	public GspMdChangeset getChangeset(String metadataId, String certId, String version) {
		if(StringUtils.isEmpty(certId)){
			if(StringUtils.isEmpty(version)){
				return changesetRepo.findByMetadataId(metadataId);
			}
			else {
				return changesetRepo.findByMetadataIdAndVersion(metadataId,version);
			}
		}else if(StringUtils.isEmpty(version)){
			changesetRepo.findByMetadataIdAndCertId(metadataId,certId);
		}
		return changesetRepo.findByMetadataIdAndCertIdAndRelatedVersion(metadataId, certId, version);
	}

	private GspMdChangesetHis BuildGspMdChangesetHis(GspMdChangeset changeset, String version) {
		GspMdChangesetHis changesetHis = new GspMdChangesetHis();
		changesetHis.setId(UUID.randomUUID().toString());
		changesetHis.setMetadataId(changeset.getMetadataId());
		changesetHis.setCertId(changeset.getCertId());
		changesetHis.setBizObjId(changeset.getBizObjId());
		changesetHis.setCode(changeset.getCode());
		changesetHis.setContent(changeset.getContent());
		changesetHis.setCreateBy(changeset.getCreateBy());
		changesetHis.setVersion(changeset.getVersion());
		changesetHis.setPreviousVersion(changeset.getPreviousVersion());
		changesetHis.setExtended(changeset.isExtended());
		changesetHis.setName(changeset.getName());
		changesetHis.setType(changeset.getType());
		changesetHis.setRelatedVersion(version);
		changesetHis.setNameSpace(changeset.getNameSpace());
		changesetHis.setExtendProperty(changeset.getExtendProperty());
		return changesetHis;
	}
	private GspMdChangeset BuildGspMdChangeset(GspMetadata metadata, AbstractCustomizedContent customizedContent, String rowId) {
		GspMdChangeset mdChangeset = new GspMdChangeset();
		mdChangeset.setId(rowId);
		mdChangeset.setMetadataId(metadata.getHeader().getId());
		mdChangeset.setCertId(metadata.getHeader().getCertId());
		mdChangeset.setRelatedVersion(metadata.getVersion());
		mdChangeset.setVersion(metadata.getVersion());
		mdChangeset.setPreviousVersion(metadata.getPreviousVersion());
		mdChangeset.setCode(metadata.getHeader().getCode());
		mdChangeset.setName(metadata.getHeader().getName());
		mdChangeset.setType(metadata.getHeader().getType());
		mdChangeset.setBizObjId(metadata.getHeader().getBizobjectID());
		mdChangeset.setExtended(true);
		mdChangeset.setNameSpace(metadata.getHeader().getNameSpace());
		mdChangeset.setExtendProperty(metadata.getExtendProperty());
		CustomizationSerializer manager = CustomizedContentSerializerHelper.getInstance().getManager(metadata.getHeader().getType());
		if (manager == null) {
			throw new LcmConfigResolveException(ErrorCodes.ECP_CONFIG_RESOLVE_0006, metadata.getHeader().getType());
		}
		String customizedContentStr =manager.serialize(customizedContent);
		mdChangeset.setContent(customizedContentStr);
		mdChangeset.setCreateBy(CustomizationServiceContext.getUserName());
		mdChangeset.setCreatedOn(LocalDateTime.now());
		mdChangeset.setLastChangedBy(CustomizationServiceContext.getUserName());
		mdChangeset.setLastChangedOn(LocalDateTime.now());
		return mdChangeset;
	}
}
